package com.suqiu.qqrobot.common.log.aspect;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author: Hua hero
 * @date: 2023/8/16
 */
@Slf4j
@Order(-10)
@Aspect
@Component
public class LogMgrAspect {

    @Pointcut("@within(com.suqiu.qqrobot.common.log.annotation.LogMgr)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object deal(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取参数列表
        Object[] args = joinPoint.getArgs();

        Object target = joinPoint.getTarget();
        //获取当前执行的方法所属的类、包
        String className = target.getClass().getName();

        //获取签名
        Signature signature = joinPoint.getSignature();

        //获取方法名
        String methodName = signature.getName();

        //String methodName = joinPoint.getSignature().getName();
        StringBuilder stringBuilder = new StringBuilder();
        for (Object arg : args) {
            stringBuilder.append(JSONUtil.toJsonStr(arg));
        }
        log.info("方法名:{},请求参数:{}", className + "#" + methodName, stringBuilder.toString());
        Object proceed;
        try {
            proceed = joinPoint.proceed();
        } catch (Throwable throwable) {
            log.info("方法名:{},请求参数:{},异常信息: {}", className + "#" + methodName, Arrays.asList(args), parseThrowableMsg(throwable));
            throw throwable;
        }
        log.info("方法名:{},请求结果:{}", className + "#" + methodName, JSONUtil.toJsonStr(proceed));
        return proceed;
    }

    private String parseThrowableMsg(Throwable throwable) {
        String throwableMsg;
        if (throwable.getStackTrace() != null && throwable.getStackTrace().length > 0) {
            StackTraceElement traceElement = throwable.getStackTrace()[0];
            throwableMsg = "message: " + throwable.getMessage() + ", class name: " + traceElement.getClassName() + ", method name: " + traceElement.getMethodName() + ", line number: " + traceElement.getLineNumber();
        } else {
            throwableMsg = throwable.getMessage();
        }
        return throwableMsg;
    }
}
